<script setup lang="ts">
import { ruleFormulaAdd } from '@fl/api/man-api/pricing-tool'
import { cloneDeep } from 'lodash-es'
import { computed, ref, toRefs } from 'vue'

import DialogCalc from './dialog-calc.vue'
import DialogItem from './dialog-item.vue'

const props = withDefaults(defineProps<{
    data?: any
    formulaIdx?: any
    isAdd: boolean
}>(), {})

const emits = defineEmits(['doAdd'])
const visible = defineModel<boolean>()
const { data, formulaIdx, isAdd } = toRefs(props)

const result = ref('')
const letRef = ref()
const items = ref<any>([])
const activeFormula = ref<any>([]) // 当前公式

const resOpts = computed(() => {
    const target = data.value?.formulaList?.length ? data.value?.formulaList : []
    const dict = target.length
        ? target.map((v: any) => {
            return {
                label: `公式${v.step}`,
                value: v.formulaId,
            }
        })
        : []
    if (isAdd.value) {
        return dict
    }
    else {
        const result = dict.slice(0, formulaIdx.value)
        return result
    }
})

function handle(item: any) {
    if (result.value?.length) {
        const lastChar = result.value.charAt(result.value.length - 1)
        // 禁止变量连续输入
        const arr = ['+', '-', '*', '/', '(']
        if (!arr.includes(lastChar))
            return
    }

    result.value += `[${item.varName}]`
}

function cancel() {
    visible.value = false
}

function reset() {
    visible.value = false
}

function doBlur(val: any) {
    items.value = cloneDeep(val)
}

function doCalc(val: string) {
    result.value += val
}

// const { mutate } = useRuleFormulaAdd()
async function doSave() {
    // 获取变量列表
    const varNameVOList = letRef.value.tableData

    if (!varNameVOList.length) {
        ElMessage({ message: '请添加变量', type: 'error' })
        return
    }

    const noRepeat = new Set([...varNameVOList.map((v: any) => v.varName)])
    if (varNameVOList.length !== noRepeat.size) {
        ElMessage.error(`存在重复变量名`)
        return
    }

    if (!result.value) {
        ElMessage({ message: '请添加公式', type: 'error' })
        return
    }

    if (!result.value.includes('[') && !result.value.includes(']')) {
        ElMessage({ message: '公式需包含变量', type: 'error' })
        return
    }

    const lastChar = result.value.charAt(result.value.length - 1)
    const arr = ['+', '-', '*', '/', '%', '.', '(', '[']
    if (arr.includes(lastChar)) {
        ElMessage({ message: '公式结尾不合法', type: 'error' })
        return
    }
    const firstChar = result.value.charAt(0)
    const arr2 = ['+', '-', '*', '/', '%', '.', ')', ']']
    if (arr2.includes(firstChar)) {
        ElMessage({ message: '公式开头不合法', type: 'error' })
        return
    }

    // 校验字段是否填写完整
    let isNext = true
    const list = cloneDeep(varNameVOList)
    let idx = 0
    list.forEach((v: any, index: number) => {
        if ((/^\s*$/.test(v.varName)) || !v.unitType || !v.calculationType
            || (v.calculationType === '1' && !v.calculationCategoryId)
            || (v.calculationType === '2' && !v.formulaId)
        ) {
            isNext = false

            idx = index + 1
        }
    })

    if (!isNext) {
        ElMessage.error(`请填完整第${idx}条数据`)
        return
    }

    // 查找最大step + 1
    let step = 1
    if (data.value?.formulaList?.length) {
        const steps = data.value?.formulaList.map((v: any) => v.step)
        step = Math.max(...steps) + 1
    }

    const params: any = {
        formula: result.value,
        step, // 公式步骤
        varNameVOList,
    }

    const target = cloneDeep(data.value)

    // 校验公式是否合法
    const res = await ruleFormulaAdd(params) // 是否只做校验表示字段，1：是，0：否}

    if (res.code === 200) {
        if (!target?.formulaList) {
            target.formulaList = []
        }
        if (data.value?.ruleId) {
            params.ruleId = data.value.ruleId
        }
        params.formulaId = res.data
        if (isAdd.value) {
            target.formulaList.push(params)
        }
        else {
            // 选中的公式详情
            const selected = target.formulaList[formulaIdx.value]
            target.formulaList[formulaIdx.value] = {
                ...selected,
                formula: result.value,
                varNameVOList,
            }
        }

        visible.value = false

        emits('doAdd', target)
    }
    else {
        ElMessage.error(res.msg)
    }
}

function init(val: any) {
    const target = cloneDeep(val)
    // 1.当前规则是否存在公式  2.存在公式 编辑时回显
    if (target?.formulaList && target.formulaList.length && !isAdd.value) {
        activeFormula.value = target.formulaList[formulaIdx.value ?? 0]
        result.value = activeFormula.value.formula
    }
}

watch(data, (val: any) => {
    if (val) {
        init(val)
    }
}, {
    immediate: true,
})
</script>

<template>
    <el-dialog v-model="visible"
               title="计算公式"
               width="880"
               close-on-press-escape
               @cancel="cancel"
               @closed="reset"
    >
        <div class="dialog-content">
            <!-- 添加变量 -->
            <DialogItem v-if="visible"
                        ref="letRef"
                        :data="activeFormula.varNameVOList"
                        :res-opts="resOpts"
                        @col-blur="doBlur"
            />

            <div class="calculator-content">
                <div class="input-box">
                    {{ result }}
                </div>

                <div class="calculator-show">
                    <div class="attributeShow p-10 border-1 border-#e6e6e6 rounded-5">
                        <template v-if="items.length">
                            <div v-for="(item, index) in items"
                                 :key="index"
                                 class="item-block"
                                 @click="handle(item)"
                            >
                                {{ item.varName }}
                            </div>
                        </template>
                    </div>
                    <!-- 计算器 -->
                    <DialogCalc v-if="visible"
                                v-model="result"
                                @change="doCalc"
                    />
                </div>
            </div>
        </div>

        <template #footer>
            <div class="text-center">
                <el-button @click="cancel">
                    取消
                </el-button>

                <el-button type="primary"
                           @click="doSave"
                >
                    保存
                </el-button>
            </div>
        </template>
    </el-dialog>
</template>

<style scoped lang="scss">
.dialog-content {
    .calculator-content {
        .input-box {
            height: 80px;
            border: 1px solid #e6e6e6;
            margin-top: 20px;
            border-radius: 5px;
            padding: 5px;
            overflow: hidden;
        }

        .calculator-show {
            width: 100%;
            display: flex;
            justify-content: space-between;
            gap: 20px;
            overflow: hidden;
            margin-top: 20px;

            .attributeShow {
                width: 65%;
                display: grid;
                grid-template-columns: repeat(4, 1fr);
                grid-template-rows: repeat(auto-fill, 40px);
                gap: 10px;

                .item-block {
                    width: 100%;
                    border: 1px solid #e6e6e6;
                    border-radius: 5px;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    cursor: pointer;
                }
            }
        }
    }
}
</style>
